<template>
  <div class="canvas-editor">
    <div class="index">
      <div class="canvas" id="canvas" ref="canvasRef"></div>
    </div>
    
    <div class="toolbar">
      <van-button @click="undo" :disabled="!canUndo">撤销</van-button>
      <van-button @click="redo" :disabled="!canRedo">重做</van-button>
      <van-button @click="triggerFileInput">上传图片</van-button>
      <input  ref="fileInput" style="display: none" type="file" @change="handleImageUpload" accept="image/*" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch,computed } from "vue";
import { useHistoryStore } from '@/stores/modules/history';

import Konva from "konva";
import { create } from "domain";
const canvasRef = ref<HTMLCanvasElement | null>(null);
let imgNode: Konva.Image | null = null;
let stage: Konva.Stage;
const layer: Konva.Layer = new Konva.Layer();

// 获取文件输入引用
const fileInput = ref<HTMLInputElement | null>(null);

const tr: Konva.Transformer = new Konva.Transformer();
const selectedNode = ref<Konva.Image>(); // 新增选中节点引用
const scaleFactor = 1.1; // 缩放系数

let currentGroup: Konva.Group | null = null;
const stageSize = { width: 300, height: 300 };
const handleSize = 10;
const maxImageSize = 150;

// 手柄元素
let handles: Konva.Circle[] = [];

const historyStore = useHistoryStore();

const canUndo = computed(() => historyStore.currentIndex > -1);
const canRedo = computed(() => {
  return historyStore.currentIndex < historyStore.history.length - 1;
});

const init = () => {
  const el = document.getElementById("canvas");
  if (!el) {
    return;
  }

  const { clientWidth, clientHeight } = el;
  const stage = new Konva.Stage({
    container: "canvas",
    width: clientWidth,
    height: clientHeight
  });

  const layer = new Konva.Layer();
  stage.add(layer);

  Konva.Image.fromURL("/src/assets/tabbar/edit.png", (image: Konva.Image) => {
    image.setAttrs({
      x: clientWidth / 2 - 25,
      y: clientHeight / 2 - 25,
      height: 50,
      width: 50,
      scaleY: 1,
      scaleX: 1
    });

    layer.add(image);
  });
};
const triggerFileInput = () => {
  fileInput.value?.click();
};
const handleImageUpload = (e: Event) => {
  const input = e.target as HTMLInputElement;
  const file = input.files?.[0];
  if (file) {
    const reader = new FileReader();
    reader.onload = e => {
      const image = new Image();
      image.src = e.target?.result as string;
      image.onload = () => createImage(image);
      // image.onload = () => {
      //   const group = new Konva.Group();

      //   imgNode = new Konva.Image({
      //     image: image,
      //     draggable: true,
      //     x: 50,
      //     y: 50,
      //     width: 100,
      //     height: 100,
      //     offset: {
      //       // offset的设置是使得围绕中心旋转：x:50,y:50
      //       x: 50,
      //       y: 50
      //     }
      //   });
      //   console.log("imgNode", imgNode);

      //   layer.add(imgNode);

      //   console.log("imgNode.x", imgNode.x()); //70
      //   console.log("imgNode.widdth()", imgNode.width()); //100

      //   // 创建右下角旋转手柄
      //   const rotateHandle = new Konva.Circle({
      //     // x: 120,  // 初始位置：x + width
      //     // y: 120,  // 初始位置：y + height
      //     x: imgNode.width(), // 初始位置：x + width
      //     y: imgNode.height(), // 初始位置：y + height
      //     radius: 8,
      //     fill: "rgba(255,0,0,0.6)",
      //     draggable: true
      //   });

      //   // 新增组变换监听
      //   group.on("transform dragmove", () => {
      //     rotateHandle.position({
      //       x: imgNode.width(),
      //       y: imgNode.height()
      //     });
      //   });

      //   // 旋转逻辑
      //   let startAngle = 0;
      //   rotateHandle.on("dragstart", () => {
      //     const absPos = group.getAbsolutePosition();
      //     console.log("点击手柄", absPos);
      //     const center = {
      //       x: absPos.x + imgNode.width() / 2,
      //       y: absPos.y + imgNode.height() / 2
      //     };
      //     const pos = rotateHandle.getStage()?.getPointerPosition();
      //     console.log("pos", pos);
      //     if (pos) {
      //       const newAngle = Math.atan2(pos.y - center.y, pos.x - center.x);
      //       if (e.type === "dragstart") {
      //         startAngle = newAngle;
      //       } else {
      //         imgNode.rotation((newAngle - startAngle) * (180 / Math.PI));
      //         layer.batchDraw();
      //       }
      //     }
      //   });

      //   rotateHandle.on("dragmove", () => {
      //     console.log("移动手柄");
      //     const center = {
      //       x: imgNode.x() + imgNode.width() / 2,
      //       y: imgNode.y() + imgNode.height() / 2
      //     };
      //     const pos = rotateHandle.getStage()?.getPointerPosition();
      //     if (pos) {
      //       const newAngle = Math.atan2(pos.y - center.y, pos.x - center.x);
      //       imgNode.rotation((newAngle - startAngle) * (180 / Math.PI));
      //       layer.batchDraw();
      //     }
      //   });

      //   // 将图片和手柄组合

      //   group.add(imgNode);
      //   group.add(rotateHandle);
      //   layer.add(group);

      //   // var triggerTime = -1000;
      //   // var scale = 1;
      //   // var angularSpeed = 190;
      //   // var anim = new Konva.Animation(function(frame: any) {
      //   //     if (frame.time - triggerTime < 1000){
      //   //         return false;
      //   //     }

      //   //     triggerTime = frame.time;

      //   //     var angleDiff = frame.timeDiff * angularSpeed / 1000;
      //   //     scale *= -1;
      //   //     imgNode.scale({x: scale, y: 1});
      //   //     // kImage1.rotate(angleDiff);          // 旋转
      //   //     // kImage2.scale({x: scale, y: 1});    // 左右镜像
      //   //     // kImage3.scale({x: 1, y: scale});    // 上下翻转
      //   // }, layer);
      //   // anim.start();
      //   // saveHistory('上传图片');
      // };
    };
    reader.readAsDataURL(file);
  }





};

  //创建四个手柄
  const createHandles = (group: Konva.Group) => { 
    console.log("createHandles", group);

    // 添加中心点标记（蓝色）
    // const centerMarker = new Konva.Circle({
    //   radius: 5,
    //   fill: 'blue',
    //   x: 10,  // 相对于 group 原点
    //   y: 10
    // });

    // // 添加左上角标记（红色）
    // const originMarker = new Konva.Circle({
    //   radius: 13,
    //   fill: 'blue',
    //   x: group.offsetX(),
    //   y: group.offsetY()
    // });
    // group.add( centerMarker, originMarker);


    // 获取图片组实际渲染尺寸
    const rect = group.getClientRect();
    // console.log("rect", rect);
    const imgWidth = rect.width;
    const imgHeight = rect.height;

    // 基于组中心坐标系计算四角坐标
    const handlePositions = [
      {
        // 左上角（相对组中心）
        x: 0,
        y: 0,
        color: "#ff4444",
        onClick: () => {
          // 保存删除前的完整状态
          
          console.log("删除前的状态", historyStore.history);
          historyStore.currentIndex = -1
          historyStore.$reset();  // 新增：重置历史状态
          // 修复顺序：先移除再销毁
          group.remove();
          // group.destroy();
          destroyHandles();
          // currentGroup = null;
          // layer.batchDraw();
          // // 强制清理舞台
          // layer.draw();
          // stage.batchDraw();
          
          // 重置上传输入 防止删除后无法重新上传图片
          const fileInput = document.querySelector(
            'input[type="file"]'
          ) as HTMLInputElement;
          if (fileInput) fileInput.value = "";
        }
      },
      {
        // 右上角
        x: imgWidth,
        y: 0,
        color: "#00ff00"
      },
      {
        // 右下角
        x: imgWidth,
        y: imgHeight,
        color: "#2196F3"
      },
      {
        // 左下角
        x: 0,
        y: imgHeight,
        color: "#ffeb3b",
        onClick: () => flipHorizontal(group)
      }
    ];

    handles = handlePositions.map(pos => {
      const handle = new Konva.Circle({
        x: pos.x,
        y: pos.y,
        radius: handleSize,
        fill: pos.color,
        draggable: true,
        visible: true,
        stroke: "white",
        strokeWidth: 2,
        name: 'target-handle' // 添加唯一标识
      });

      if (pos.onClick) {
        handle.on("click tap", e => {
          e.cancelBubble = true; // 阻止事件冒泡
          pos.onClick!();
        });
      }
      group.add(handle); // 新增手柄到组中
      // layer.add(handle);
      return handle;
    });

    // 设置操作手柄功能
    setupDeleteHandle(handles[0], group); // 左上删除
    setupRotationHandle(handles[1], group); // 右上旋转
    setupScaleHandle(handles[2], group); // 右下缩放
    setupFlipHorizontalHandle(handles[3], group); // 左下翻转
  };
  const createImage = (img: HTMLImageElement) => {
    // 计算缩放比例
    console.log("img", img.width, img.height);
    const scale = Math.min(maxImageSize / img.width, maxImageSize / img.height);
    const group = new Konva.Group({
      x: stageSize.width / 2, // 组在舞台上的初始位置
      y: stageSize.height / 2,
      width: 100,
      height: 100,
      offsetX: (img.width * scale) / 2,// X轴中心点偏移 //中心点，以图片中心为原点，x轴向右为正，y轴向下为正，默认是图片左上角为原点，x轴向右为正，y轴向下为正，所以需要偏移
      offsetY: (img.height * scale) / 2,// Y轴中心点偏移
      draggable: true // 添加可拖动属性
    });
    // 添加拖拽结束事件监听

    // 添加组点击事件
    group.on("click tap", (e) => {
      e.cancelBubble = true; // 阻止事件冒泡
      currentGroup = group;
      showHandles();
    });
    // 新增：创建完成后立即绑定currentGroup
    currentGroup = group;
    const konvaImg = new Konva.Image({
      image: img,
      width: img.width * scale, // 按比例缩放图片
      height: img.height * scale,
      name: 'target-image' // 添加唯一标识
    });
    // 图片拖拽结束事件监听
    group.on('dragend', () => {
      saveCurrentState();
    });
      // 替换为更可靠的等待方式 拖拽完图片添加撤回操作
  const checkImageLoaded = () => {
    if (konvaImg.image()?.complete) {
      // 确保Konva完成内部渲染
      setTimeout(() => {
        saveCurrentState();//图片加载完成后调用`saveCurrentState()`，将当前状态推送到历史记录中。
        console.log('初始状态保存完成');
      }, 50);
    } else {
      setTimeout(checkImageLoaded, 50);
    }
  };
  checkImageLoaded();
    const border = new Konva.Rect({
      // 初始位置和尺寸与图片一致
      width: konvaImg.width(),
      height: konvaImg.height(),
      stroke: "#0099ff",
      strokeWidth: 2,
      dash: [4, 4],
      // offsetX: konvaImg.width() / 2, // 中心对齐
      // offsetY: konvaImg.height() / 2
    });
    group.add(konvaImg, border);
    layer.add(group);
    createHandles(group);
  }
 
  // 操作手柄 删除
  const setupDeleteHandle = (handle: Konva.Circle, group: Konva.Group) => {
    handle.on("dragstart", () => {
    });
    handle.on("dragmove", () => {  
      handle.position({
        x: 0,//图片的一半*2
        y: 0
      });
    });
  }
//  操作手柄 旋转
  const setupRotationHandle = (handle: Konva.Circle, group: Konva.Group) => {
    let lastAngle = 0;
    console.log("setupRotationHandle", handle);
    handle.on("dragstart", () => {
      const center = group.getAbsolutePosition();
      const pos = stage.getPointerPosition()!;
      lastAngle = Math.atan2(pos.y - center.y, pos.x - center.x);
    
    });

    handle.on("dragmove", () => {
      const center = group.getAbsolutePosition();
      const pos = stage.getPointerPosition()!;
      const newAngle = Math.atan2(pos.y - center.y, pos.x - center.x);
      // 获取实际渲染尺寸（包含旋转和缩放）
      const rect = group.getClientRect();
      group.rotation( group.rotation() + (newAngle - lastAngle) * (180 / Math.PI));
      
      // 动态更新手柄位置(保持手柄在图片中心)
      handle.position({
        x: group.offsetX()*2,//图片的一半*2
        y: 0
      });
      lastAngle = newAngle;
    });
    // handle.on('dragend', () => saveCurrentState());
  }
//  操作手柄 缩放
  const  setupScaleHandle = (handle: Konva.Circle, group: Konva.Group)  =>{
    let startScale = 1;
    let startDistance = 0;
  
    handle.on("dragstart", () => {
      const center = group.getAbsolutePosition();
      const pos = stage.getPointerPosition()!;
      startScale = Math.abs(group.scaleX()); // 获取绝对值
      startDistance = Math.hypot(pos.x - center.x, pos.y - center.y);
    });
  
    handle.on("dragmove", () => {
      const center = group.getAbsolutePosition();
      const pos = stage.getPointerPosition()!;
      const currentDistance = Math.hypot(pos.x - center.x, pos.y - center.y);
  
      const scaleFactor = currentDistance / startDistance;
      const newScale = startScale * scaleFactor;
      
      // 保持原有翻转方向
      const scaleSign = group.scaleX() > 0 ? 1 : -1;
      group.scaleX(newScale * scaleSign);
      group.scaleY(newScale);
      
      // 更新手柄位置时考虑翻转状态
      const offsetX = group.scaleX() > 0 ? group.offsetX()*2 : group.offsetX() * 2;//防止翻转后手柄位置不对 正数为正方向，负数为反方向
      handle.position({
        x: offsetX,
        y: group.offsetY()*2
      });
    });
    // handle.on('dragend', () => saveCurrentState());
  }
 //  操作手柄 水平翻转
 const setupFlipHorizontalHandle = (handle: Konva.Circle, group: Konva.Group) =>{
  handle.on("dragstart", () => {
  });

  handle.on("dragmove", () => {  
    handle.position({
      x: 0,//图片的一半*2
      y: group.offsetY()*2
    });
  });
 }
const flipHorizontal = (group: Konva.Group) => {
  console.log("flipHorizontal", group);
  // group.scaleX(-group.scaleX()); // 修改scaleY为scaleX
  // 保存当前缩放比例
  const currentScale = Math.abs(group.scaleX());
  // 根据当前缩放方向决定新缩放值
  group.scaleX(group.scaleX() > 0 ? -currentScale : currentScale);
  saveCurrentState();
}
  // 新增状态保存方法
const saveCurrentState = ()=> {
  if (!currentGroup) return;

  // 添加完整状态信息
  const state = {
    type: 'modify',
    x: currentGroup.x(),
    y: currentGroup.y(),
    rotation: currentGroup.rotation(),
    scaleX: currentGroup.scaleX(),
    scaleY: currentGroup.scaleY(),
    width: currentGroup.width(),
    height: currentGroup.height(),
    // 新增关键属性
    offsetX: currentGroup.offsetX(),
    offsetY: currentGroup.offsetY()
  };

  // 添加调试信息
  console.log('保存历史记录1:', state);
  console.log('当前历史索引:', historyStore.currentIndex);
  
  historyStore.push({
    data: JSON.stringify(state),
    description: '图片状态变更'
  });
  console.log('保存历史记录2:', historyStore.history);
}
//显示手柄和边框
const showHandles =()=> {
  handles.forEach(h => h.visible(true));
  if (currentGroup) {
    currentGroup.findOne("Rect")?.visible(true);
  }
  layer.batchDraw();
}
 //隐藏手柄和边框
const hideHandles = () => {
  handles.forEach(h => h.visible(false));
  if (currentGroup) {
    currentGroup.findOne("Rect")?.visible(false);
  }
  layer.batchDraw();
};
const destroyHandles = () => {
  handles.forEach(h => h.destroy());
  handles = [];
};
// 新增状态应用方法
const applyStateToGroup = (state: any) => {
  if (!currentGroup) return;
  // 新增空状态处理
  if (state === null) {
    currentGroup.destroy();
    currentGroup = null;
    destroyHandles();
    return;
  };
  // 使用setAttrs一次性设置所有属性
  currentGroup.setAttrs({
    x: state.x,
    y: state.y,
    rotation: state.rotation,
    scaleX: state.scaleX,
    scaleY: state.scaleY,
    width: state.width,
    height: state.height,
    offsetX: state.offsetX,  // 添加offset恢复
    offsetY: state.offsetY
  });
  // 强制刷新整个舞台
  layer.draw();
  stage.batchDraw();
};
// 修改撤销/重做方法
const undo = async () => {
  if (!canUndo.value) return;
  
  const prevState = await historyStore.undo();
  if (prevState && currentGroup) {
    const state = JSON.parse(prevState.data);
    applyStateToGroup(state);
  }
};

const redo = async () => {
  if (!canRedo.value) return;
  const nextState = await historyStore.redo();
  if (nextState && currentGroup) {
    const state = JSON.parse(nextState.data);
    applyStateToGroup(state);
    layer.batchDraw();
  }
};
// 初始化Canvas
onMounted(() => {
  const { clientWidth, clientHeight } = canvasRef.value || {
    clientWidth: 0,
    clientHeight: 0
  };
  console.log("clientWidth", clientWidth, "clientHeight", clientHeight);
  stage = new Konva.Stage({
    container: "canvas",
    width: clientWidth,
    height: clientHeight
  });
  stage.add(layer);
  // 舞台点击事件需要等stage初始化后绑定
  stage.on("click", e => {
    if (e.target === stage) {
      hideHandles();
    }
  });

  // init();
});
// 首先，我要确认用户提到的边框是指哪个元素。在代码中，用户创建了一个Konva.Rect作为边框，添加到group中。这个边框的宽度和高度设置为konvaImg的尺寸，因此边框的尺寸应该和图片一致。

// 接下来，分析Konva.Group的配置。group的offsetX和offsetY被设置为图片缩放后尺寸的一半，这意味着group的原点（默认在左上角）被偏移到了图片的中心。因此，group的旋转和缩放会围绕这个中心点进行。

// 然后，考虑边框的位置。由于边框是直接添加到group中的，并且没有设置额外的偏移，它的位置是相对于group的原点（即偏移后的中心点）的。因此，边框的左上角实际上位于group的中心点，导致边框的中心点与group的中心点重合。

// 但是，可能需要验证这一点。因为group的offsetX和offsetY改变了其原点，而边框的位置是相对于这个原点的。如果边框的x和y没有额外设置，默认是0，那么边框的左上角会在group的原点，即图片中心。这样，边框的实际中心点应该是group的原点加上边框宽度和高度的一半，但由于group的原点已经是图片中心，所以边框的中心点可能与group的原点一致。

// 另外，用户可能混淆了group的中心点和边框元素的中心点。由于group的offset已经将原点移到图片中心，而边框的尺寸与图片相同，且位置相对于group的原点，因此边框的中心点确实与group的原点重合。

// 最后，总结结论：边框的中心点由group的offset配置决定，即位于图片的中心，也就是stageSize的中间位置加上group的x和y偏移后的位置。需要参考group的x和y以及offset来计算实际中心点。
</script>

<style lang='scss' scoped>
.index {
  // padding: 20px;

  .canvas {
    background-color: #eee;
    border: 1px solid #efefef;
    height: calc(50vh);
  }
}
</style>
